// *** LICENSE HEADER ***
// Filename: ./particle.cpp
// This file is part of Nodewarz 0.1
// Nodewarz is a 3d OpenGL strategy game
// Copyright (C) 2007 CZestmyr
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// *** END LICENSE HEADER ***
#include "particle.h"

GLfloat particle::modelview[16] = {0.0f, 0.0f, 0.0f, 0.0f,
                                   0.0f, 0.0f, 0.0f, 0.0f,
                                   0.0f, 0.0f, 0.0f, 0.0f,
                                   0.0f, 0.0f, 0.0f, 0.0f};
GLfloat particle::transX = 0.0f;
GLfloat particle::transY = 0.0f;
GLfloat particle::transZ = 0.0f;

particle::particle(float x, float y, float z,
                   float sx, float sy, float sz,
                   int lifetime, int fadeTime, float newSize,
                   affector* newAff, GLuint newTex,
                   float newR, float newG, float newB,
                   float fR, float fG, float fB,
                   float newAlpha) {
    posX = x;
    posY = y;
    posZ = z;
    speedX = sx;
    speedY = sy;
    speedZ = sz;
    aff = newAff;
    texture = newTex;
    age = 0;
    life = lifetime;
    fadeout = fadeTime;
    size = newSize;
    alpha = newAlpha;
    r = newR;
    g = newG;
    b = newB;
    fadeR = fR;
    fadeG = fG;
    fadeB = fB;
}

void particle::SetNext(particle* nextParticle) {
    next = nextParticle;
}

bool particle::Update(int dt) {
    //Update position
    posX += speedX / 1000 * dt;
    posY += speedY / 1000 * dt;
    posZ += speedZ / 1000 * dt;
    //Update particle age
    age += dt;

    //Check, whether we have to be fading and set current color
    if (age > life - fadeout) {
        float linearFadeCoeff = (float)(life - age) / fadeout;
        float inverseLinearFadeCoeff = 1.0f - linearFadeCoeff;
        currentAlpha = linearFadeCoeff * alpha;
        curR = linearFadeCoeff * r + inverseLinearFadeCoeff * fadeR;
        curG = linearFadeCoeff * g + inverseLinearFadeCoeff * fadeG;
        curB = linearFadeCoeff * b + inverseLinearFadeCoeff * fadeB;
    } else {
        curR = r;
        curG = g;
        curB = b;
        currentAlpha = alpha;
    }

    //Return false for to-be-destroyed particles
    if (age > life)
        return false;
    //Affect this particle with the particle affector, if applicable
    if (aff)
        aff->Modify(this, dt);
    return true;
}

void particle::Draw() {
    //Calculate particle translation from the modelview matrix
    glLoadIdentity();
    transX = posX * modelview[0] + posY * modelview[4] + posZ * modelview[8] + modelview[12];
    transY = posX * modelview[1] + posY * modelview[5] + posZ * modelview[9] + modelview[13];
    transZ = posX * modelview[2] + posY * modelview[6] + posZ * modelview[10] + modelview[14];
    glTranslatef(transX, transY, transZ);

    //Draw the particle billboard
    glBindTexture(GL_TEXTURE_2D, texture);
    glColor4f(curR, curG, curB, currentAlpha);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0f, 0.0f);
    glVertex3f(- size, - size, 0.0f);
    glTexCoord2f(1.0f, 0.0f);
    glVertex3f(size, - size, 0.0f);
    glTexCoord2f(1.0f, 1.0f);
    glVertex3f(size, size, 0.0f);
    glTexCoord2f(0.0f, 1.0f);
    glVertex3f(- size, size, 0.0f);
    glEnd();
}

void particle::SetModelviewMatrix() {
    glGetFloatv(GL_MODELVIEW_MATRIX, modelview);
}
